package cn.wen.yinxiu.member.service.impl;

import cn.wen.yinxiu.common.constant.Constant;
import cn.wen.yinxiu.common.convention.errorcode.ErrorCode;
import cn.wen.yinxiu.common.convention.exception.RepeatDataException;
import cn.wen.yinxiu.common.enums.DelEnum;
import cn.wen.yinxiu.common.enums.StatusEnum;
import cn.wen.yinxiu.member.dao.UsersDao;
import cn.wen.yinxiu.member.entity.ChatRecordEntity;
import cn.wen.yinxiu.member.entity.GroupEntity;
import cn.wen.yinxiu.member.entity.UsersEntity;
import cn.wen.yinxiu.member.service.ChatRecordService;
import cn.wen.yinxiu.member.service.GroupService;
import cn.wen.yinxiu.member.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.wen.yinxiu.common.toolkit.PageUtils;
import cn.wen.yinxiu.common.toolkit.Query;

import cn.wen.yinxiu.member.dao.TalkBoxDao;
import cn.wen.yinxiu.member.entity.TalkBoxEntity;
import cn.wen.yinxiu.member.service.TalkBoxService;

import static cn.wen.yinxiu.common.constant.Constant.TalkType.Friend;
import static cn.wen.yinxiu.common.constant.Constant.TalkType.Group;


@Service("talkBoxService")
public class TalkBoxServiceImpl extends ServiceImpl<TalkBoxDao, TalkBoxEntity> implements TalkBoxService {

    @Autowired
    private TalkBoxDao talkBoxDao;

    @Autowired
    private UsersDao usersDao;

    @Value("${yinxiu.notice.pageSize}")
    private Integer pageSize;

    @Autowired
    private ChatRecordService chatRecordService;

    @Autowired
    private GroupService groupService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<TalkBoxEntity> page = this.page(
                new Query<TalkBoxEntity>().getPage(params),
                new QueryWrapper<TalkBoxEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public List<TalkBoxEntity> queryTalkBoxInfoListByUserId(Long userId) {
        // 1.通过用户Id获取所有的聊天窗Id
        QueryWrapper<TalkBoxEntity> queryWrapper = new QueryWrapper<>();
        // 查询条件 (数据库使用联合索引查询  速度较快)
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("is_deleted", DelEnum.NORMAL.code());
        queryWrapper.eq("status", StatusEnum.NORMAL_USE.code());
        queryWrapper.orderByDesc("top").orderByDesc("update_time");
        return talkBoxDao.selectList(queryWrapper);
    }

    @Override
    public boolean saveTalkBoxInfo(TalkBoxEntity talkBox) {
        // 1.判断是否存在该聊天框
        if (null != queryTalkBox(talkBox.getUserId(), talkBox.getTalkId()))
            throw new RepeatDataException(ErrorCode.DATA_REPEAT_ERROR);
        // 2.添加到数据库中
        return talkBoxDao.insert(talkBox) > 0;
    }

    @Override
    public void deleteUserTalk(Long talkBoxId) {
        TalkBoxEntity target = new TalkBoxEntity();
        target.setId(talkBoxId);
        target.setIsDeleted(DelEnum.DELETE.code());
        target.setDeletedRemark("用户正常删除窗口！");
        talkBoxDao.updateById(target);
    }

    @Override
    public List<Long> queryTalkBoxGroupIdList(Long userId) {
        return talkBoxDao.selectTalkBoxGroupIdList(userId, Group.getCode(),
                StatusEnum.NORMAL_USE.code(), DelEnum.NORMAL.code());
    }

    @Override
    public TalkBoxEntity getUserTalkBox(Long userId, Long talkId, Integer talkType) {
        QueryWrapper<TalkBoxEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("talk_id", talkId);
        queryWrapper.eq("talk_type", talkType);
        return talkBoxDao.selectOne(queryWrapper);
    }

    @Override
    public List<TalkBoxInfo> queryTalkBoxInfoList(Long userId, Integer talkPage) {
        // 1.分页获取一页的聊天窗口 + 对应的一页聊天记录
        List<TalkBoxEntity> talkBoxList = queryTalkBoxPageListByUserId(userId, talkPage);
        return getTalkBoxInfoList(userId, talkBoxList);
    }

    private List<TalkBoxInfo> getTalkBoxInfoList(Long userId, List<TalkBoxEntity> talkBoxList) {
        List<TalkBoxInfo> talkBoxInfoList = new ArrayList<>();
        for (TalkBoxEntity talkBox : talkBoxList) {
            TalkBoxInfo talkBoxInfo = new TalkBoxInfo();
            if (Friend.getCode().equals(talkBox.getTalkType())) {
                UsersEntity user = usersDao.selectById(talkBox.getTalkId());
                talkBoxInfo.setUserId(userId);
                talkBoxInfo.setTalkType(Friend.getCode());
                talkBoxInfo.setTalkId(user.getId());
                talkBoxInfo.setTalkName(user.getUsername());
                talkBoxInfo.setTalkAvatar(user.getAvatar());
                talkBoxInfo.setTalkTime(user.getLastLoginTime());
                talkBoxInfo.setOnLine(user.getOnlineStatus());
                talkBoxInfo.setTop(talkBox.getTop());
                List<ChatRecordVO> chatRecordDtoList = new ArrayList<>();
                List<ChatRecordEntity> chatRecordInfoList = chatRecordService
                        .queryUserChatRecordList(userId,
                        user.getId(), Constant.NUM_ONE);
                for (ChatRecordEntity entity : chatRecordInfoList) {
                    ChatRecordVO chatRecordVO = new ChatRecordVO();
                    chatRecordVO.setTalkId(talkBoxInfo.getTalkId());
                    boolean msgType = user.getId() == entity.getUserId();
                    // 自己发的消息
                    if (msgType) {
                        chatRecordVO.setUserId(entity.getUserId());
                        chatRecordVO.setMsgUserType(0); // 消息类型[0自己/1好友]
                    }
                    // 好友发的消息
                    else {
                        chatRecordVO.setUserId(entity.getFriendId());
                        chatRecordVO.setMsgUserType(1); // 消息类型[0自己/1好友]
                    }
                    chatRecordVO.setMsgContent(entity.getMessage());
                    chatRecordVO.setMsgType(entity.getMsgType());
                    chatRecordVO.setMsgTime(entity.getMsgTime());
                    chatRecordDtoList.add(chatRecordVO);
                }
                talkBoxInfo.setChatRecordList(chatRecordDtoList);
            } else if (Group.getCode().equals(talkBox.getTalkType())) {
                GroupEntity groups = groupService.queryTalkBoxById(talkBox.getTalkId());
                talkBoxInfo.setUserId(userId);
                talkBoxInfo.setTalkType(Group.getCode());
                talkBoxInfo.setTalkId(groups.getId());
                talkBoxInfo.setTalkName(groups.getGroupName());
                talkBoxInfo.setTalkAvatar(groups.getGroupAvatar());
                talkBoxInfo.setOnLine(-1);
                talkBoxInfo.setTop(talkBox.getTop());
                List<ChatRecordVO> chatRecordDtoList = new ArrayList<>();
                List<ChatRecordEntity> chatRecordInfoList = chatRecordService.queryGroupsChatRecordList(
                        talkBoxInfo.getTalkId(), Constant.NUM_ONE);
                for (ChatRecordEntity chatRecordInfo : chatRecordInfoList) {
                    UsersEntity usersEntity = usersDao.selectById(chatRecordInfo.getUserId());
                    ChatRecordVO ChatRecordVO = new ChatRecordVO();
                    ChatRecordVO.setTalkId(talkBoxInfo.getTalkId());
                    ChatRecordVO.setUserId(usersEntity.getId());
                    ChatRecordVO.setUserNickName(usersEntity.getUsername());
                    ChatRecordVO.setUserAvatar(usersEntity.getAvatar());
                    ChatRecordVO.setMsgContent(chatRecordInfo.getMessage());
                    ChatRecordVO.setMsgTime(chatRecordInfo.getMsgTime());
                    boolean msgType = usersEntity.getId() == chatRecordInfo.getUserId();
                    ChatRecordVO.setMsgUserType(msgType ? 0 : 1); // 消息类型[0自己/1好友]
                    ChatRecordVO.setMsgType(chatRecordInfo.getMsgType());
                    chatRecordDtoList.add(ChatRecordVO);
                }
                talkBoxInfo.setChatRecordList(chatRecordDtoList);
            }
            talkBoxInfoList.add(talkBoxInfo);
        }
        return talkBoxInfoList;
    }

    @Override
    public boolean topChatTalkBox(Long chatBoxId) {
        TalkBoxEntity target = new TalkBoxEntity();
        target.setId(chatBoxId);
        target.setTop(Constant.NUM_ONE);
        return talkBoxDao.updateById(target) > 0;
    }

    @Override
    public boolean deleteChatTalkBox(Long chatBoxId) {
        TalkBoxEntity target = new TalkBoxEntity();
        target.setId(chatBoxId);
        target.setIsDeleted(DelEnum.DELETE.code());
        target.setDeletedRemark("用户正常删除窗口！");
        return talkBoxDao.updateById(target) > 0;
    }

    @Override
    public boolean addTalkBoxInfo(Long userId, Long talkId, Integer talkType) {
        // 1.先删除已存在的相关窗口
        TalkBoxEntity res = getUserTalkBox(userId, talkId, talkType);
        if (res != null) {
            if (res.getIsDeleted() == DelEnum.NORMAL.code() && res.getStatus() == StatusEnum.NORMAL_USE.code())
                return true;
            // 2.修改状态为未删除状态
            TalkBoxEntity target = new TalkBoxEntity();
            target.setId(res.getId());
            target.setIsDeleted(DelEnum.NORMAL.code());
            return talkBoxDao.updateById(target) > 0;
        } else {
            // 2.添加窗口  TODO 聊天记录第一条还需要判断是否需要添加窗口
            TalkBoxEntity talkBox = new TalkBoxEntity();
            talkBox.setUserId(userId);
            talkBox.setTalkId(talkId);
            talkBox.setTalkType(talkType);
            talkBox.setStatus(StatusEnum.NORMAL_USE.code());
            return saveTalkBoxInfo(talkBox);
        }
    }

    @Override
    public List<TalkBoxInfo> queryTalkBoxInfoListByType(Long userId, Integer talkType, Integer talkPage) {
        // 1.分页获取一页的聊天窗口 + 对应的一页聊天记录
        List<TalkBoxEntity> talkBoxList = queryTalkBoxPageListByUserIdType(userId, talkType, talkPage);
        return getTalkBoxInfoList(userId, talkBoxList);
    }

    private List<TalkBoxEntity> queryTalkBoxPageListByUserIdType(Long userId, Integer talkType, Integer talkPage) {
        // 1.通过用户Id获取所有的聊天窗Id
        QueryWrapper<TalkBoxEntity> queryWrapper = new QueryWrapper<>();
        // 查询条件 (数据库使用联合索引查询  速度较快)
        queryWrapper.eq("user_id", userId);
        if (talkType != 0) {
            queryWrapper.eq("talk_type", talkType);
        }
        queryWrapper.eq("is_deleted", DelEnum.NORMAL.code());
        queryWrapper.eq("status", StatusEnum.NORMAL_USE.code());
        queryWrapper.orderByDesc("top").orderByDesc("update_time");
        queryWrapper.last("LIMIT " + pageSize * (talkPage - 1) + "," + pageSize);
        return talkBoxDao.selectList(queryWrapper);
    }

    private List<TalkBoxEntity> queryTalkBoxPageListByUserId(Long userId, Integer talkPage) {
        // 1.通过用户Id获取所有的聊天窗Id
        QueryWrapper<TalkBoxEntity> queryWrapper = new QueryWrapper<>();
        // 查询条件 (数据库使用联合索引查询  速度较快)
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("is_deleted", DelEnum.NORMAL.code());
        queryWrapper.eq("status", StatusEnum.NORMAL_USE.code());
        queryWrapper.orderByDesc("top").orderByDesc("update_time");
        queryWrapper.last("LIMIT " + pageSize * (talkPage - 1) + "," + pageSize);
        return talkBoxDao.selectList(queryWrapper);
    }

    private TalkBoxEntity queryTalkBox(Long userId, Long talkId) {
        // 查询条件  user_id talk_id is_deleted 建立NORMAL联合索引
        QueryWrapper<TalkBoxEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("talk_id", talkId);
        queryWrapper.eq("is_deleted", DelEnum.NORMAL.code());
        return talkBoxDao.selectOne(queryWrapper);
    }


}